<template>
  <div ref="parentNode">
    <div class="header">
      <slot name="header">
        <div class="title">{{ title }}</div>
        <div class="handler">
          <slot name="headerHandler"></slot>
        </div>
      </slot>
    </div>

    <el-pagination
      :currentPage="page.currentPage"
      :page-sizes="paginationConfig.pageSizes"
      :page-size="page.pageSize"
      :layout="paginationConfig.layout && paginationConfig.layout.join(',')"
      :total="paginationConfig.total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      class="pagination"
    />

    <el-table
      :data="dataList"
      :max-height="tableHeight"
      @selection-change="selectionChange"
      :row-key="childrenProps.rowKey"
      :tree-props="childrenProps.treeProps"
      border
    >
      <el-table-column
        v-if="isShowSelectColumns"
        align="center"
        type="selection"
        width="40"
      />

      <el-table-column
        v-if="isShowIndexColumns"
        header-align="center"
        align="center"
        type="index"
        label="序号"
        width="60"
      />

      <template v-for="item in propList" :key="item.prop">
        <el-table-column
          :label="item.label"
          :min-width="item.minWidth"
          :show-overflow-tooltip="item.showOverflowTooltip"
          align="center"
        >
          <template #default="{ row }">
            <slot :name="item.slotName" :row="row">
              {{ row[item.prop] }}
            </slot>
          </template>
        </el-table-column>
      </template>
    </el-table>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, nextTick, ref, watch } from 'vue';
import type { ITablePropList, IPagination } from './types/index';
export * from './types/index';

export default defineComponent({
  props: {
    title: {
      type: String,
      default: '',
    },

    paginationConfig: {
      type: Object as PropType<IPagination>,
      required: true,
    },

    dataList: {
      type: Array,
      default: () => [],
    },

    propList: {
      type: Array as PropType<ITablePropList>,
      required: true,
    },

    isShowIndexColumns: {
      type: Boolean,
      default: false,
    },

    isShowSelectColumns: {
      type: Boolean,
      default: false,
    },

    childrenProps: {
      type: Object,
      default: () => ({}),
    },

    page: {
      type: Object,
      default: () => ({
        currentPage: 0,
        pageSize: 10,
      }),
    },
  },

  emits: ['selectionChange', 'update:page'],

  setup(props, ctx) {
    const parentNode = ref(null);
    const tableHeight = ref(50);

    const initHeight = () => {
      nextTick(() => {
        tableHeight.value = (parentNode.value as any).parentNode.offsetHeight;
      });
    };

    const selectionChange = (v: any) => {
      ctx.emit('selectionChange', v);
    };

    watch(() => props.dataList, initHeight, {
      deep: true,
    });

    const handleSizeChange = function (pageSize: number) {
      ctx.emit('update:page', { ...props.page, pageSize });
    };

    const handleCurrentChange = function (currentPage: number) {
      ctx.emit('update:page', { ...props.page, currentPage });
    };

    return {
      parentNode,
      tableHeight,
      selectionChange,

      handleSizeChange,
      handleCurrentChange,
    };
  },
});
</script>

<style lang="less" scoped>
.header {
  display: flex;
  height: 45px;
  padding: 0 5px;
  justify-content: space-between;
  align-items: center;

  .title {
    font-size: 20px;
    font-weight: 700;
  }

  .handler {
    align-items: center;
  }
}

.footer {
  margin-top: 15px;
}

.pagination {
  text-align: right;
}
</style>
